import {defined,JulianDate,SceneMode,Transforms,Cartesian3,Matrix4} from '@cesiumjs';

// cesium 模拟地球自转: https://blog.csdn.net/lovefengruoqing/article/details/109486587

//options可以设置时钟的一些参数，比如自转开始的时间，自转的速度等
function RotaterX(viewer, options) {

  options = options || {
    multiplier: 500
  };

  // 地球自转
  let icrf = function() {
    if (!viewer || viewer.scene.mode !== SceneMode.SCENE3D) {
      return;
    }
    const icrfToFixed = Transforms.computeIcrfToFixedMatrix(viewer.clock.currentTime);
    if (defined(icrfToFixed)) {
      const camera = viewer.camera;
      const offset = Cartesian3.clone(camera.position);
      const transform = Matrix4.fromRotationTranslation(icrfToFixed);
      camera.lookAtTransform(transform, offset);
    }
  };

  this.start = function() {
    if (!viewer) {
      return;
    }
    if (viewer.clock) {
      const keys = Object.keys(options);
      for (let k of keys) {
        viewer.clock[k] = options[k];
      }
    }
    viewer.scene.postUpdate.addEventListener(icrf);
  };

  this.stop = function() {
    if (!viewer) {
      return;
    }
    viewer.clock.multiplier = 1;
    viewer.scene.postUpdate.removeEventListener(icrf);
    // viewer = undefined;
  };
}

const $defaultOptions = {
  multiplier: 1,
  // spinRate: 1,
}

function Rotater1(viewer, options) {

  viewer.clock.shouldAnimate = true;

  options = options || $defaultOptions;
  viewer.clock.multiplier = options.multiplier; //速度

  var previousTime = viewer.clock.currentTime.secondsOfDay;

  //地租自转事件
  function onTickCallback() {
    viewer.clock.multiplier = options.multiplier || $defaultOptions.multiplier; //速度
    // const spinRate = options.spinRate || $defaultOptions.spinRate; //速度
    const currentTime = viewer.clock.currentTime.secondsOfDay;
    const delta = (currentTime - previousTime) / 10000;
    // viewer.scene.camera.rotate(Cartesian3.UNIT_Z, spinRate * delta);
    viewer.scene.camera.rotate(Cartesian3.UNIT_Z, delta);
    previousTime = currentTime;
  }

  this.start = function() {
    if (!viewer) {
      return;
    }
    viewer.clock.onTick.addEventListener(onTickCallback);
  };

  this.stop = function() {
    if (!viewer) {
      return;
    }
    viewer.clock.onTick.removeEventListener(onTickCallback);
  };
}

//////////////////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////////////////


/**
 * @param {Object} viewer
 * @param {Object} options
 * @param {Object} fnTick
 */
function Rotater2(viewer, options, fnTick) {
  const {
    camera,
    clock,
    scene
  } = viewer;

  clock.shouldAnimate = true;

  let playing = false;


  options = options || $defaultOptions;

  this.resetCurrTime = function() {
    clock.currentTime = JulianDate.addHours(JulianDate.now(new Date()), 0, new JulianDate());
  }

  function updateClock() {
    const multiplier = options.multiplier || $defaultOptions.multiplier || 1;
    clock.multiplier = multiplier; //速度
  }

  updateClock();

  // 地球自转关键代码
  let previousTime = clock.currentTime;
  const icrf = () => {

    updateClock();

    const {
      currentTime
    } = clock;
    // const interval = JulianDate.toDate(currentTime) - JulianDate.toDate(previousTime);

    fnTick && fnTick(JulianDate.toDate(currentTime))

    if (!playing) return;

    if (scene.mode !== SceneMode.SCENE3D) {
      previousTime = clock.currentTime;
      return;
    }

    const delta = (currentTime.secondsOfDay - previousTime.secondsOfDay);
    const offset = (2 * Math.PI / (24 * 60 * 60)) * delta;

    camera.rotate(
      Cartesian3.UNIT_Z,
      offset,
    );

    previousTime = currentTime;
  };

  this.start = function() {
    playing = true;
    previousTime = clock.currentTime;
  };

  this.stop = function() {
    playing = false;
    // clock.onTick.removeEventListener(icrf);
  };

  this.destroy = function() {
    this.stop();
    clock.onTick.removeEventListener(icrf);
  };

  clock.onTick.addEventListener(icrf);
}

const Rotater = Rotater2;

export default Rotater;
